package com.hengyue.config.jackson;


import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.boot.jackson.JsonComponent;
import org.springframework.context.annotation.Bean;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;


import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.TimeZone;

@JsonComponent
public class JacksonConfig {

    private static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    private static final String TIME_ZONE = "GMT+8";

    /**
     * 创建一个Jackson2ObjectMapperBuilderCustomizer的Bean，用于自定义Jackson的ObjectMapper构建器。
     *
     * @return 一个Jackson2ObjectMapperBuilderCustomizer实例，用于自定义Jackson的ObjectMapper构建器。
     */
    @Bean
    public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {

        return builder -> {
            customizeLongSerialization(builder);
            customizeDateTimeAndRegisterModule(builder);
            configureOtherSettings(builder);
        };
    }

    /**
     * 自定义 Long 类型的序列化方式，将 Long 类型序列化为 String 类型
     * @param builder Jackson2ObjectMapperBuilder 构建器
     */
    private void customizeLongSerialization(Jackson2ObjectMapperBuilder builder) {
        builder.serializerByType(Long.class, ToStringSerializer.instance)
                .serializerByType(Long.TYPE, ToStringSerializer.instance);
    }

    /**
     * 自定义日期时间格式
     * @param builder Jackson2ObjectMapperBuilder 构建器
     */
    private void customizeDateTimeAndRegisterModule(Jackson2ObjectMapperBuilder builder) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DATE_TIME_FORMAT);
        LocalDateTimeSerializer localDateTimeSerializer = new LocalDateTimeSerializer(formatter);
        JavaTimeModule javaTimeModule = new JavaTimeModule();
        javaTimeModule.addSerializer(LocalDateTime.class, localDateTimeSerializer);
        builder.modules(javaTimeModule);
        builder.timeZone(TimeZone.getTimeZone(TIME_ZONE));
        builder.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
    }


    /**
     * 配置其他全局设置
     * @param builder Jackson2ObjectMapperBuilder 构建器
     */
    private void configureOtherSettings(Jackson2ObjectMapperBuilder builder) {
        // 反序列化时，遇到空对象不抛出异常
        builder.failOnEmptyBeans(false);
        // 反序列化时，遇到未知属性不抛出异常
        builder.failOnUnknownProperties(false);
        // 序列化时，格式化输出 JSON，提高可读性
        builder.indentOutput(true);
    }



}